from typing import List, Optional
from sqlalchemy.orm import Session
from datetime import datetime, date
from ..models.task import Task as TaskModel, TaskStatus, TaskPriority
from ..models.project import Project
from ..models.user import User
from ..schemas.task import TaskCreate, TaskUpdate
from fastapi import HTTPException, status

class TaskService:
    def __init__(self, db: Session):
        self.db = db

    def get_tasks(self, skip: int = 0, limit: int = 100) -> List[TaskModel]:
        """获取任务列表"""
        return self.db.query(TaskModel).offset(skip).limit(limit).all()

    def get_task(self, task_id: int) -> Optional[TaskModel]:
        """根据ID获取任务"""
        return self.db.query(TaskModel).filter(TaskModel.id == task_id).first()

    def create_task(self, task_data: TaskCreate) -> TaskModel:
        """创建任务"""
        # 检查项目是否存在
        project = self.db.query(Project).filter(Project.id == task_data.project_id).first()
        if not project:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="项目不存在"
            )
        
        # 检查指派用户是否存在
        if task_data.assigned_to:
            user = self.db.query(User).filter(User.id == task_data.assigned_to).first()
            if not user:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="指派的用户不存在"
                )
        
        # 检查截止日期是否在项目日期范围内
        if task_data.due_date:
            if project.start_date and task_data.due_date < project.start_date:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="任务截止日期不能早于项目开始日期"
                )
            if project.end_date and task_data.due_date > project.end_date:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="任务截止日期不能晚于项目结束日期"
                )
        
        # 创建新任务
        db_task = TaskModel(**task_data.dict())
        self.db.add(db_task)
        self.db.commit()
        self.db.refresh(db_task)
        return db_task

    def update_task(self, task_id: int, task_data: TaskUpdate) -> TaskModel:
        """更新任务信息"""
        db_task = self.get_task(task_id)
        if not db_task:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="任务不存在"
            )
        
        # 检查项目是否存在（如果更新了项目）
        if task_data.project_id and task_data.project_id != db_task.project_id:
            project = self.db.query(Project).filter(Project.id == task_data.project_id).first()
            if not project:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="项目不存在"
                )
        
        # 检查指派用户是否存在（如果更新了指派用户）
        if task_data.assigned_to and task_data.assigned_to != db_task.assigned_to:
            user = self.db.query(User).filter(User.id == task_data.assigned_to).first()
            if not user:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="指派的用户不存在"
                )
        
        # 检查截止日期是否在项目日期范围内（如果更新了截止日期）
        if task_data.due_date:
            project_id = task_data.project_id if task_data.project_id else db_task.project_id
            project = self.db.query(Project).filter(Project.id == project_id).first()
            
            if project.start_date and task_data.due_date < project.start_date:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="任务截止日期不能早于项目开始日期"
                )
            if project.end_date and task_data.due_date > project.end_date:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="任务截止日期不能晚于项目结束日期"
                )
        
        # 更新任务信息
        for key, value in task_data.dict(exclude_unset=True).items():
            setattr(db_task, key, value)
        
        self.db.commit()
        self.db.refresh(db_task)
        return db_task

    def delete_task(self, task_id: int) -> None:
        """删除任务"""
        db_task = self.get_task(task_id)
        if not db_task:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="任务不存在"
            )
        
        self.db.delete(db_task)
        self.db.commit()

    def get_tasks_by_project(self, project_id: int) -> List[TaskModel]:
        """根据项目获取任务列表"""
        # 检查项目是否存在
        project = self.db.query(Project).filter(Project.id == project_id).first()
        if not project:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="项目不存在"
            )
        
        return self.db.query(TaskModel).filter(TaskModel.project_id == project_id).all()

    def get_tasks_by_user(self, user_id: int) -> List[TaskModel]:
        """获取用户的任务列表"""
        # 检查用户是否存在
        user = self.db.query(User).filter(User.id == user_id).first()
        if not user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        return self.db.query(TaskModel).filter(TaskModel.assigned_to == user_id).all()

    def get_overdue_tasks(self) -> List[TaskModel]:
        """获取逾期任务列表"""
        today = date.today()
        return self.db.query(TaskModel).filter(
            TaskModel.due_date < today,
            TaskModel.status != TaskStatus.COMPLETED
        ).all()

    def get_task_stats_by_status(self, project_id: Optional[int] = None) -> dict:
        """获取任务状态统计"""
        query = self.db.query(TaskModel)
        
        if project_id:
            # 检查项目是否存在
            project = self.db.query(Project).filter(Project.id == project_id).first()
            if not project:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="项目不存在"
                )
            query = query.filter(TaskModel.project_id == project_id)
        
        # 统计各状态的任务数量
        stats = {status.value: 0 for status in TaskStatus}
        
        for status in TaskStatus:
            count = query.filter(TaskModel.status == status).count()
            stats[status.value] = count
        
        # 计算总数
        stats["total"] = sum(stats.values())
        
        return stats